package org.developer.websocketserver.handler;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketServerHandshaker;
import io.netty.handler.codec.http.websocketx.WebSocketServerHandshakerFactory;
import lombok.extern.slf4j.Slf4j;
import org.developer.websocketserver.context.ConnectContext;
import org.developer.websocketserver.context.ServerContext;
import org.springframework.stereotype.Component;

import java.net.InetSocketAddress;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

@Component
@ChannelHandler.Sharable
@Slf4j
public class HttpServerHandler extends SimpleChannelInboundHandler<FullHttpRequest> {

    //当有新的 channel 增加的时候
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {

        //获取当前的 channel
        Channel channel = ctx.channel();
        //向其他 channel 发送上线消息
        ServerContext.channelGroup.writeAndFlush(new TextWebSocketFrame(String.format("[服务器]\t用户：%s 加入聊天室！\n", channel.remoteAddress())));
        //添加 channel 到 group 里面
        ServerContext.channelGroup.add(channel);

        log.info("[新连接]: 当前连接数={}",ServerContext.channelGroup.size());

        // 向新用户发送欢迎信息
        channel.writeAndFlush(
                new TextWebSocketFrame(String.format("你好，%s欢迎来到Netty聊天室\n", channel.remoteAddress())));

    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) throws Exception {

        String uri = req.uri();
        log.info("uri={}",uri);

//        Map paramMap = getParamMap(uri.substring(2));
//
//        String userId = Optional
//                .ofNullable(paramMap.get("userId").toString())
//                .orElseThrow(() -> new RuntimeException("userId不能为空"));
//
//        log.info("userId={}",userId);

        Channel channel = ctx.channel();
        InetSocketAddress address = (InetSocketAddress) channel.remoteAddress();
        String ip = address.getAddress().getHostAddress();
        int port = address.getPort();
        log.info("有client加入,[ip]:{},[port]:{}",ip,port);

        log.info("req.headers={}",req.headers());

        //构造握手响应返回,本机测试
        // TODO: 2020/7/24 待研究
        WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(
                "ws://" + req.headers().get(HttpHeaderNames.HOST) + uri,
                null, false
        );

        WebSocketServerHandshaker handshaker = wsFactory.newHandshaker(req);
        if (handshaker == null) {

            //返回 res 和 channelPromise
            WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel());
        } else {

            handshaker.handshake(ctx.channel(), req);
        }
    }

    /**
     * 解析路径参数
     * @param uri 请求路径
     * @return 路径参数Map
     */
    public Map getParamMap(String uri) {

        Map<String, Object> params = new HashMap<>();
        String[] split = uri.split("&");
        for (String param : split) {

            String[] paramSplit = param.split("=");
            params.put(paramSplit[0], paramSplit[1]);
        }

        return params;
    }
}
